#include "libraries.h"
#include "CCreature.h"
#include "lists.h"
#include "extern.h"

ObjectsList OL;
BuildingsList BL;
CreaturesTeam GCT;
CreaturesTeam CECT, NECT, LECT;

void OE_Move()
{	
	CObject *pObject;
	OBJECT_ITERATOR iterator = OL.begin(); 
	while(iterator != OL.end())
	{
		pObject=*iterator;
		if(pObject->Move()==0) 
		{
			delete pObject;
			iterator = OL.erase(iterator);     
		}
		else
		{
			iterator++;
		}
	}
	CBuilding *pBuilding;
	BUILDING_ITERATOR iterator1 = BL.begin(); 
	while(iterator1 != BL.end())
	{
		pBuilding=*iterator1;
		pBuilding->Move();
		iterator1++;
	}
	CCreature *pCreature;
	CREATURE_ITERATOR iterator2 = GCT.begin(); 
	while(iterator2 != GCT.end())
	{
		pCreature=*iterator2;
		if(pCreature->Move()==0) 
		{
			delete pCreature;
			iterator2 = GCT.erase(iterator2);     
		}
		else
		{
			iterator2++;
		}
	}
	iterator2 = CECT.begin();
	while(iterator2 != CECT.end())
	{
		pCreature=*iterator2;
		if(pCreature->Move()==0)
		{
			delete pCreature;
			iterator2 = CECT.erase(iterator2);     
		}
		else
		{
			iterator2++; 
		}
	}
	iterator2 = NECT.begin();
	while(iterator2 != NECT.end())
	{
		pCreature=*iterator2;
		if(pCreature->Move()==0)
		{
			delete pCreature;
			iterator2 = NECT.erase(iterator2);     
		}
		else
		{
			iterator2++; 
		}
	}
	iterator2 = LECT.begin();
	while(iterator2 != LECT.end())
	{
		pCreature=*iterator2;
		if(pCreature->Move()==0)
		{
			delete pCreature;
			iterator2 = LECT.erase(iterator2);     
		}
		else
		{
			iterator2++; 
		}
	}
}

void OE_Process()
{
	CCreature *PCreature1;
	CCreature *PCreature2;
	for(CREATURE_ITERATOR iterator1 = GCT.begin(); iterator1 != GCT.end(); iterator1++)
	{
		PCreature1 = *iterator1;
		if (PCreature1->Ready() == 1)
		{
			for(CREATURE_ITERATOR iterator2 = CECT.begin(); iterator2 != CECT.end(); iterator2++)
			{
				PCreature2 = *iterator2;
				PCreature1->Process(PCreature2);
			}
			for(CREATURE_ITERATOR iterator2 = NECT.begin(); iterator2 != NECT.end(); iterator2++)
			{
				PCreature2 = *iterator2;
				PCreature1->Process(PCreature2);
			}
			for(CREATURE_ITERATOR iterator2 = LECT.begin(); iterator2 != LECT.end(); iterator2++)
			{
				PCreature2 = *iterator2;
				PCreature1->Process(PCreature2);
			}
		}
	}
	for(CREATURE_ITERATOR iterator1 = CECT.begin(); iterator1 != CECT.end(); iterator1++)
	{
		PCreature1 = *iterator1;
		if (PCreature1->Ready() == 1)
		{
			for(CREATURE_ITERATOR iterator2 = GCT.begin(); iterator2 != GCT.end(); iterator2++)
			{
				PCreature2 = *iterator2;
				PCreature1->Process(PCreature2);
			}
			for(CREATURE_ITERATOR iterator2 = LECT.begin(); iterator2 != LECT.end(); iterator2++)
			{
				PCreature2 = *iterator2;
				PCreature1->Process(PCreature2);
			}
		}
	}
	for(CREATURE_ITERATOR iterator1 = NECT.begin(); iterator1 != NECT.end(); iterator1++)
	{
		PCreature1 = *iterator1;
		if (PCreature1->Ready() == 1)
		{
			for(CREATURE_ITERATOR iterator2 = GCT.begin(); iterator2 != GCT.end(); iterator2++)
			{
				PCreature2 = *iterator2;
				PCreature1->Process(PCreature2);
			}
		}
	}
	for(CREATURE_ITERATOR iterator1 = LECT.begin(); iterator1 != LECT.end(); iterator1++)
	{
		PCreature1 = *iterator1;
		if (PCreature1->Ready() == 1)
		{
			for(CREATURE_ITERATOR iterator2 = GCT.begin(); iterator2 != GCT.end(); iterator2++)
			{
				PCreature2 = *iterator2;
				PCreature1->Process(PCreature2);
			}
			for(CREATURE_ITERATOR iterator2 = CECT.begin(); iterator2 != CECT.end(); iterator2++)
			{
				PCreature2 = *iterator2;
				PCreature1->Process(PCreature2);
			}
		}
	}
}

void OE_Draw()
{
	CCreature *PCreature;
	for(CREATURE_ITERATOR iterator = GCT.begin(); iterator != GCT.end(); iterator++)
	{
		PCreature = *iterator;
		PCreature->Draw();
	}
	for(CREATURE_ITERATOR iterator = CECT.begin(); iterator != CECT.end(); iterator++)
	{
		PCreature = *iterator;
		PCreature->Draw();
	}
	for(CREATURE_ITERATOR iterator = NECT.begin(); iterator != NECT.end(); iterator++)
	{
		PCreature = *iterator;
		PCreature->Draw();
	}
	for(CREATURE_ITERATOR iterator = LECT.begin(); iterator != LECT.end(); iterator++)
	{
		PCreature = *iterator;
		PCreature->Draw();
	}
	CObject *PObject;
	for(OBJECT_ITERATOR iterator = OL.begin(); iterator != OL.end(); iterator++)
	{
		PObject = *iterator;
		PObject->Draw();
	}
}

void OE_FindNEMotherCreature(CCreature *MyP, int MotherType, int MyX, int MyY)
{
	double Distance = 200;
	CCreature *pCreature;
	for(CREATURE_ITERATOR iterator = NECT.begin(); iterator != NECT.end(); iterator++)
	{
		pCreature = *iterator;
		if (pCreature->GetType() == MotherType)
		{
			for (int i = 0; i < 5; i++)
			{
				if (pCreature->IsPlaceFree(i) == 1)
				{
					double a = (pCreature->GetX()-MyX)*(pCreature->GetX()-MyX)+(pCreature->GetY()-MyY)*(pCreature->GetY()-MyY);
					if (a < Distance) Distance = a;
				}
			}
		}
	}
	if (Distance == 200) return;
	for(CREATURE_ITERATOR iterator = NECT.begin(); iterator != NECT.end(); iterator++)
	{
		pCreature = *iterator;
		if (pCreature->GetType() == MotherType)
		{
			for (int i = 0; i < 5; i++)
			{
				if (pCreature->IsPlaceFree(i) == 1)
				{
					double a = (pCreature->GetX()-MyX)*(pCreature->GetX()-MyX)+(pCreature->GetY()-MyY)*(pCreature->GetY()-MyY);
					if (a == Distance)
					{
						pCreature->SetParasiteCreature(MyP,i);
						MyP->SetMotherCreature(pCreature,i);
						return;
					}
				}
			}
		}
	}
}

void OE_FindLEMotherCreature(CCreature *MyP, int MotherType, int MyX, int MyY)
{
	double Distance = 200;
	CCreature *pCreature;
	for(CREATURE_ITERATOR iterator = LECT.begin(); iterator != LECT.end(); iterator++)
	{
		pCreature = *iterator;
		if (pCreature->GetType() == MotherType)
		{
			for (int i = 0; i < 5; i++)
			{
				if (pCreature->IsPlaceFree(i) == 1)
				{
					double a = (pCreature->GetX()-MyX)*(pCreature->GetX()-MyX)+(pCreature->GetY()-MyY)*(pCreature->GetY()-MyY);
					if (a < Distance) Distance = a;
				}
			}
		}
	}
	if (Distance == 200) return;
	for(CREATURE_ITERATOR iterator = LECT.begin(); iterator != LECT.end(); iterator++)
	{
		pCreature = *iterator;
		if (pCreature->GetType() == MotherType)
		{
			for (int i = 0; i < 5; i++)
			{
				if (pCreature->IsPlaceFree(i) == 1)
				{
					double a = (pCreature->GetX()-MyX)*(pCreature->GetX()-MyX)+(pCreature->GetY()-MyY)*(pCreature->GetY()-MyY);
					if (a == Distance)
					{
						pCreature->SetParasiteCreature(MyP,i);
						MyP->SetMotherCreature(pCreature,i);
						return;
					}
				}
			}
		}
	}
}

void OE_FindCEMotherCreature(CCreature *MyP, int MotherType, int MyX, int MyY)
{
	double Distance = 200;
	CCreature *pCreature;
	for(CREATURE_ITERATOR iterator = CECT.begin(); iterator != CECT.end(); iterator++)
	{
		pCreature = *iterator;
		if (pCreature->GetType() == MotherType)
		{
			for (int i = 0; i < 5; i++)
			{
				if (pCreature->IsPlaceFree(i) == 1)
				{
					double a = (pCreature->GetX()-MyX)*(pCreature->GetX()-MyX)+(pCreature->GetY()-MyY)*(pCreature->GetY()-MyY);
					if (a < Distance) Distance = a;
				}
			}
		}
	}
	if (Distance == 200) return;
	for(CREATURE_ITERATOR iterator = CECT.begin(); iterator != CECT.end(); iterator++)
	{
		pCreature = *iterator;
		if (pCreature->GetType() == MotherType)
		{
			for (int i = 0; i < 5; i++)
			{
				if (pCreature->IsPlaceFree(i) == 1)
				{
					double a = (pCreature->GetX()-MyX)*(pCreature->GetX()-MyX)+(pCreature->GetY()-MyY)*(pCreature->GetY()-MyY);
					if (a == Distance)
					{
						pCreature->SetParasiteCreature(MyP,i);
						MyP->SetMotherCreature(pCreature,i);
						return;
					}
				}
			}
		}
	}
}

void OE_SelectUnit(int X, int Y)
{
	CCreature *PCreature;
	for(CREATURE_ITERATOR iterator = NECT.begin(); iterator != NECT.end(); iterator++)
	{
		PCreature = *iterator;
		if (PCreature->GetX() == X && PCreature->GetY() == Y)
		{
			if (PCreature->IsMother() == 1)
			{
				pSelectedCreature = *iterator;
				return;
			}
		}
	}
	for(CREATURE_ITERATOR iterator = CECT.begin(); iterator != CECT.end(); iterator++)
	{
		PCreature = *iterator;
		if (PCreature->GetX() == X && PCreature->GetY() == Y)
		{
			if (PCreature->IsMother() == 1)
			{
				pSelectedCreature = *iterator;
				return;
			}
		}
	}
	for(CREATURE_ITERATOR iterator = LECT.begin(); iterator != LECT.end(); iterator++)
	{
		PCreature = *iterator;
		if (PCreature->GetX() == X && PCreature->GetY() == Y)
		{
			if (PCreature->IsMother() == 1)
			{
				pSelectedCreature = *iterator;
				return;
			}
		}
	}
	for(CREATURE_ITERATOR iterator = NECT.begin(); iterator != NECT.end(); iterator++)
	{
		PCreature = *iterator;
		if (PCreature->GetX() - 1 <= X && PCreature->GetX() + 1 >= X && PCreature->GetY() - 1 <= Y && PCreature->GetY() + 1 >= Y)
		{
			if (PCreature->IsMother() == 1)
			{
				pSelectedCreature = *iterator;
				return;
			}
		}
	}
	for(CREATURE_ITERATOR iterator = CECT.begin(); iterator != CECT.end(); iterator++)
	{
		PCreature = *iterator;
		if (PCreature->GetX() - 1 <= X && PCreature->GetX() + 1 >= X && PCreature->GetY() - 1 <= Y && PCreature->GetY() + 1 >= Y)
		{
			if (PCreature->IsMother() == 1)
			{
				pSelectedCreature = *iterator;
				return;
			}
		}
	}
	for(CREATURE_ITERATOR iterator = LECT.begin(); iterator != LECT.end(); iterator++)
	{
		PCreature = *iterator;
		if (PCreature->GetX() - 1 <= X && PCreature->GetX() + 1 >= X && PCreature->GetY() - 1 <= Y && PCreature->GetY() + 1 >= Y)
		{
			if (PCreature->IsMother() == 1)
			{
				pSelectedCreature = *iterator;
				return;
			}
		}
	}
}